﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PureMVC.Interfaces;
using PureMVC.Other;
using System;
using PureMVC.Patterns.Observer;

namespace PureMVC.Core
{
    public partial class Controller : IController
    {
        public Controller(string _key)
        {
            if (instanceMap.ContainsKey(_key) && multitionKey != null)
            {
                throw new Exception(MULTITON_MSG);
            }
            multitionKey = _key;
            instanceMap.Add(multitionKey, new WeakLazy<IController>(() => this));
            commandMap = new Dictionary<string, Func<ICommand>>();
            InitializeController();
        }

        protected virtual void InitializeController()
        {
            view = View.GetInstance(multitionKey, () => new View(multitionKey));
        }

        public virtual void ExecuteCommand(INotification _notification)
        {
            if (commandMap.ContainsKey(_notification.Name))
            {
                var command = commandMap[_notification.Name]();
                command.InitializeNotifier(multitionKey);
                command.Execute(_notification);
            }
        }

        public virtual bool HasCommand(string _notificationName)
        {
            return commandMap.ContainsKey(_notificationName);
        }

        /// <summary>
        /// 注册命令
        /// </summary>
        /// <param name="_notificationName"></param>
        /// <param name="_commandClassRef"></param>
        public virtual void RegisterCommand(string _notificationName, Func<ICommand> _commandClassRef)
        {
            Func<ICommand> _;
            if (commandMap.TryGetValue(_notificationName, out _) == false)
            {
                view.RegisterObserver(_notificationName, new Observer(ExecuteCommand, this));
            }
            commandMap[_notificationName] = _commandClassRef;
        }

        /// <summary>
        /// 移除命令
        /// </summary>
        /// <param name="_notificationName"></param>
        public virtual void RemoveCommand(string _notificationName)
        {
            if (commandMap.ContainsKey(_notificationName))
            {
                commandMap.Remove(_notificationName);
                view.RemoveObserver(_notificationName, this);
            }
        }

        protected IView view;
        protected string multitionKey = null;
        protected Dictionary<string, Func<ICommand>> commandMap;
    }
}